package programs.statement;

import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Set;

import game.Ship;
import programs.expression.implementedClasses.Variable;
import programs.expression.superClasses.Expression;
import programs.expression.superClasses.ExpressionType;

public class WhileLoop extends Loop {
	
	private Expression condition;

	public WhileLoop(Statement loopStatement, Expression condition) {
		super(loopStatement);
		this.condition = condition;
	}
	
	@Override
	public boolean isValidStatement() {
		return super.isValidStatement() && getCondition().isValidExpression() && (getCondition().getReturnType() == ExpressionType.BOOLEAN);
	}
	
	public Expression getCondition() {
		return this.condition;
	}
	
	@Override
	public void setExecuter(Ship executer) {
		super.setExecuter(executer);
		getLoopStatement().setExecuter(executer);
	}
	
	@Override
	public void assignGlobalVariable(Variable variable) {
		super.assignGlobalVariable(variable);
		condition = condition.assignGlobalVariable(variable);
	}
	
	@Override
	public Set<Variable> getVariables(){
		Set<Variable> set = super.getVariables();
		set.addAll(getCondition().getVariables());
		return set;
	}

	@Override
	public Iterator<BasicStatement> getIterator() {
		return new  Iterator<BasicStatement>()  {

		private Iterator<BasicStatement> currentIterator = getLoopStatement().getIterator();
	
		public boolean hasNext() {
			if(currentIterator.hasNext())
				return true;
			if(! getLoopStatement().isEmpty() && ( (Boolean) getCondition().getValue())	)
				return true;
			return false;
		}

		public BasicStatement next() throws NoSuchElementException {
			if(!hasNext())
				throw new NoSuchElementException();
			if(currentIterator.hasNext())
				return currentIterator.next();
			else {
				currentIterator = getLoopStatement().getIterator();
				return currentIterator.next();
			}
		}

		public void remove() throws UnsupportedOperationException {
			throw new UnsupportedOperationException();
		}
	};
	}
}
